from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from book.models import BookInfo
from book.serializers import BookModelserializers
from rest_framework.generics import GenericAPIView


# 1,定义类，集成ＡＰＩＶｉｅｗ
class BookAPIView(APIView):
    def get(self, request):
        """
        View获取数据方式：
            get:
                request.GET
            post:
                request.POST
                request.body
        APIView获取数据方式
            GET:
                request.query_params    
            POST:    
                request.data
                
                
        :param request: 
        :return: 
        """""
        # 1.获取ＡＰＩＶｉｅｗ中的ＧＥＴ请求
        # print(request.query_params )
        return Response(status=status.HTTP_404_NOT_FOUND)
        pass

    def post(self, request):
        # 2.获取ＡＰＩＶｉｅｗ中的POST请求
        # print(request.data )
        pass


# 2.序列化器和APIView实现列表视图：
class BookListView(APIView):

    def get(self, request):
        # 1,查询所有的书籍
        books = BookInfo.objects.all()
        serialize = BookModelserializers(instance=books, many=True)
        return Response(serialize.data)

    def post(self, request):
        # 1,获取参数
        data_dict = request.data
        # 2,创建序列化器
        serialize = BookModelserializers(data=data_dict)
        # 3,数据校验，入库
        serialize.is_valid(raise_exception=True)
        serialize.save()

        # 4,返回响应
        return Response(serialize.data, status=status.HTTP_201_CREATED)


# 3, 获取单个书籍,修改单本书籍,删除单本书籍 (序列化器和APIView实现详情视图)
class BookDetailView(APIView):
    def get(self, request, book_id):
        # 1,获取书籍
        book = BookInfo.objects.get(id=book_id)

        # 2,创建序列化器对象
        serializers = BookModelserializers(instance=book)

        # 4,返回响应
        return Response(serializers.data, status=status.HTTP_200_OK)

    def put(self, request, book_id):
        # 1,获取数据,获取对象
        data_dict = request.data
        book = BookInfo.objects.get(id=book_id)

        # 2,创建序列化器
        serializers = BookModelserializers(instance=book, data=data_dict)

        # 3．校验
        serializers.is_valid(raise_exception=True)

        # 3,数据入库
        serializers.save()
        # 4,返回响应
        return Response(request.data, status=status.HTTP_201_CREATED)

    def delete(self, request, book_id):
        # 1,删除书籍
        BookInfo.objects.get(id=book_id).delete()

        # 2,返回响应
        return Response(status=status.HTTP_204_NO_CONTENT)


# 4.二级视图ＧｅｎｅｒｉｃＡＰＩＶｉｅｗ特点
"""
１．GenericAPLView,继承ＡＰＩView类，为列表视图，和详情试图，添加了常用的行为和属性
        行为：
            get_queryset(), 获取queryset数据集
            get_serializer，获取serializer_class序列化对象
            get_object()   通过lookup_field获取单个对象
            
        属性：
            queryset,  通用数据集
            serializer_class    通用序列化器
            lookup_field:  默认是PK，可以手动改为id

２，可以和一个或多个ｍｉｘｉｎ类配合使用

"""


# ５.使用二级视图ＧｅｎｅｒｉｃＡＰＩＶｉｅｗ实现列表视图：
class BookListGebericAPIView(GenericAPIView):
    # 1.提供公共的属性
    queryset = BookInfo.objects.all()
    serializer_class = BookModelserializers

    def get(self, request):
        # 1,查询所有的书籍
        # books = self.queryset
        books = self.get_queryset()

        # serialize = BookModelserializers(instance=books,many=True)
        # serialize =self.serializer_class(instance=books,many=True)
        # serialize =self.get_serializer_class()(instance=books,many=True)
        serialize = self.get_serializer(instance=books, many=True)
        return Response(serialize.data)

    def post(self, request):
        # 1,获取参数
        data_dict = request.data
        # 2,创建序列化器
        # serialize = BookModelserializers(data=data_dict)
        serialize = self.get_serializer(data=data_dict)
        # 3,数据校验，入库
        serialize.is_valid(raise_exception=True)
        serialize.save()

        # 4,返回响应
        return Response(serialize.data, status=status.HTTP_201_CREATED)


# ６,使用二级视图ＧｅｎｅｒｉｃＡＰＩＶｉｅｗ实现详情视图
class BookDetailGebericAPIView(GenericAPIView):
    # 1.提供公共的属性
    queryset = BookInfo.objects.all()
    serializer_class = BookModelserializers

    def get(self, request, pk):
        # 1,获取书籍
        book = self.get_object()  # 根据ｂｏｏｋ＿ｉｄ　到queryset中取出书籍对象

        # 2,创建序列化器对象
        serializers = self.get_serializer(instance=book)

        # 4,返回响应
        return Response(serializers.data, status=status.HTTP_200_OK)

    def put(self, request, pk):
        # 1,获取数据,获取对象
        data_dict = request.data
        book = self.get_object()

        # 2,创建序列化器
        serializers = self.get_serializer(instance=book, data=data_dict)

        # 3．校验
        serializers.is_valid(raise_exception=True)

        # 3,数据入库
        serializers.save()
        # 4,返回响应
        return Response(request.data, status=status.HTTP_201_CREATED)

    def delete(self, request, pk):
        # 1,删除书籍
        self.get_object().delete()

        # 2,返回响应
        return Response(status=status.HTTP_204_NO_CONTENT)


# 7.Mixin类
'''
特点：
1.mixin类提供用于基本视图行为（列表视图，详情视图）的操作
2.配合二级视图GenericAPIView使用

类名称					  提供方法			功能
ListModelMixin			list			查询所有的数据
CreateModelMixin		create			创建单个对象
RetrieveModelMixin		retrieve		获取单个对象
UpdateModelMixin		update			更新单个对象
DestroyModelMixin		destroy			删除单个对象
'''

from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, \
    RetrieveModelMixin


# 8.mixin和使用二级视图GenericAPIView实现列表视图：
class BookListMixinGebericAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
    # 1.提供公共的属性
    queryset = BookInfo.objects.all()
    serializer_class = BookModelserializers

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)


##9,mixin和使用二级视图GenericAPIView实现详情视图
class BookDetailMixinGebericAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    # 1.提供公共的属性
    queryset = BookInfo.objects.all()
    serializer_class = BookModelserializers

    def get(self, request, pk):
        return self.retrieve(request)

    def put(self, request, pk):
        return self.update(request)

    def delete(self, request, pk):
        return self.destroy(request)


# 三级视图
'''
特点：
如果没有大量自定义的行为，可以使用通用视图（三级视图）解决
常用的三级视图：
类名称				  父类					提供方法	 		  作用				
CreateAPIView		GenericAPIView,			post				创建单个对象
					CreateModelMixin
    
ListAPIView			GenericAPIView,			get					查询所有的数据
					ListModelMixin
    
RetrieveAPIView    	GenericAPIView,			get					获取单个对象
					RetrieveModelMixin
    
DestroyAPIView		GenericAPIView, 		delete				删除单个对象
					DestroyModelMixin

UpdateAPIView 		GenericAPIView, 		put and patch		更新单个对象
					UpdateModelMixin
'''

from rest_framework.generics import ListAPIView,CreateAPIView,RetrieveAPIView ,UpdateAPIView ,DestroyAPIView
#10.三级视图,实现列表，详情视图
class BookListThirdView(ListAPIView,CreateAPIView):
    # 1.提供公共的属性
    queryset = BookInfo.objects.all()
    serializer_class = BookModelserializers


class BookDetailThirdView(RetrieveAPIView,UpdateAPIView,DestroyAPIView ):
    # 1.提供公共的属性
    queryset = BookInfo.objects.all()
    serializer_class = BookModelserializers



#视图集
"""
特点：
	1.可以将一组相关操作，放在一个类中进行完成、
    2.不提供get，post方法，使用resrieve，create方法来代替
    3.可以将标准的请求方式(get,post,put,delete),和mixin中的方法做映射
常见的视图集：
类名称				  			  父类						     作用	
ViewSet							APIView							可以做路由映射

GenericViewSet					GenericAPIView					可以做路由映射，可以使用三个属性，方法
								ViewSetMixin

ModelViewSet					GenericAPIView					所有的增删改查，可以使用三个属性，方法
								5个mixin类

ReadOnlyModelViewSet			GenericAPIView,					获取单个和所有数据，可以使用三个属性，方法
								RetrieveModelMixin,
    							ListModelMixin


"""

from rest_framework.viewsets import ReadOnlyModelViewSet
class BooksReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookModelserializers

# ModelViewSet,所有的增删改查，可以使用三个属性，方法(实现列表，详情视图)
from rest_framework.viewsets import ModelViewSet
class BooksModelViewSet(ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookModelserializers